package com.google.code.task;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import static com.google.code.task.TaskResultType.*;

public class RetryFailoverDecorator extends AbstractFluentTask {
  @SuppressWarnings("unused")
  private static final Log LOG = LogFactory
      .getLog(RetryFailoverDecorator.class);
  static final int DEFAULT_RETRYCOUNT = 3;

  private Task task;
  private Task failoverTask;
  private int retryCount = DEFAULT_RETRYCOUNT;
  private TaskResultType expected = SUCCESS;

  public RetryFailoverDecorator(Task task) {
    this.task = task;
  }

  public TaskResultType execute() {
    for (int i = 0; i < retryCount; i++) {
      TaskResultType result = task.execute();
      if (result == expected) {
        return TaskResultType.SUCCESS;
      }
    }

    if (failoverTask == null) {
      return TaskResultType.FAILURE;
    }

    TaskResultType failoverResult = failoverTask.execute();
    return failoverResult == SUCCESS ? FAILOVER : FAILURE;
  }

  public RetryFailoverDecorator failover(Task failoverTask) {
    this.failoverTask = failoverTask;
    return this;
  }

  public RetryFailoverDecorator retryCount(int retryCount) {
    this.retryCount = retryCount;
    return this;
  }

  public RetryFailoverDecorator expected(TaskResultType expected) {
    this.expected = expected;
    return this;
  }

  Task getTask() {
    return task;
  }
  
  Task getFailover() {
    return failoverTask;
  }
  
  TaskResultType getExpected() {
    return expected;
  }
  
  int getRetryCount() {
    return retryCount;
  }
}
